#include <iostream>
#include "Aes.h"
#include "ScheduleKey.h"

#include "FiniteFieldMul.h"
#include "SubstitutionTable.h"
#include "ShiftRows.h"
#include "ScheduleKey.h"
#include "MixColumns.h"

int main(void) {
//    unsigned char pt[17], key[17];
//    //定义原文pt
//    //定义密钥key
//    unsigned char expansionkey[15 * 16];
//    int i;
//    int j;
//    printf("You are welcome to use the AES machine in SDU\n");
//    printf("Please enter plaintext (length = 16):\n");
//    scanf("%s", pt);
//    printf("please input key: \n");
//    scanf("%s", key);
//
//    //加密过程
//    ScheduleKey(key, expansionkey, 4, 10);//密钥扩展生成
//    AesEncrypt(pt, expansionkey, 10);//调用AES 加密
//    printf("ciphertext: ");
//
//    //输出密文
//    for (i = 0; i < 16; i++) {
//        printf("%02x ", pt[i]);
//    }
//    printf("\n");
//    printf("\n");
//
//    //解密过程
//    Contrary_AesEncrypt(pt, expansionkey, 10);//调用AES 解密
//    printf("The decrypted plaintext is: ");
//
//    //输出明文
//    for (i = 0; i < 16; i++) {
//        printf("%c ", pt[i]);
//    }
//    printf("\n");
//    printf("\n");

    unsigned char res = x2time((unsigned char) 0x1F);
    unsigned char res2 = x2time(res);
    unsigned char res3 = x2time(res2);
    unsigned char res4 = x2time(res3);
    unsigned char res5 = x2time(res4);
    printf("%02x ", res);
    printf("%02x ", res2);
    printf("%02x ", res3);
    printf("%02x ", res4);
    printf("%02x \n", res5);

    unsigned char resx3 = x3time((unsigned char) 0x1F);
    printf("%02x \n", resx3);

    unsigned char resx9 = x9time((unsigned char) 0x1F);
    printf("%02x \n", resx9);

    unsigned char resxB = xBtime((unsigned char) 0x1F);
    printf("%02x \n", resxB);

    unsigned char resxD = xDtime((unsigned char) 0x1F);
    printf("%02x \n", resxD);

    unsigned char resxE = xEtime((unsigned char) 0x1F);
    printf("%02x \n", resxE);

    printf("%02x %02x %02x %02x \n", sbox[0x01], sbox[0x06], sbox[0x09], sbox[0x2E]);

    unsigned char *matrix = new unsigned char[16]{
            '1', '2', '3', '4',
            '5', '6', '7', '8',
            '9', 'a', 'b', 'c',
            'd', 'e', 'f', 'g',
    };
    printf("---------------------\n");
    printf("%c %c %c %c \n%c %c %c %c \n%c %c %c %c \n%c %c %c %c \n",
           matrix[0], matrix[4], matrix[8], matrix[12],
           matrix[1], matrix[5], matrix[9], matrix[13],
           matrix[2], matrix[6], matrix[10], matrix[14],
           matrix[3], matrix[7], matrix[11], matrix[15]
    );
    ShiftRows(matrix);
    printf("---------------------\n");
    printf("%c %c %c %c \n%c %c %c %c \n%c %c %c %c \n%c %c %c %c \n",
           matrix[0], matrix[4], matrix[8], matrix[12],
           matrix[1], matrix[5], matrix[9], matrix[13],
           matrix[2], matrix[6], matrix[10], matrix[14],
           matrix[3], matrix[7], matrix[11], matrix[15]
    );
    printf("---------------------\n");
    unsigned char *initKey = new unsigned char[]{
            0x01, 0x02, 0x03, 0x04,
            0x0a, 0x0b, 0x0c, 0x0d,
            0xa1, 0xb2, 0xc3, 0xd4,
            0x11, 0x22, 0x33, 0x44,
    };
    unsigned char *result = new unsigned char[16 * 11];
    ScheduleKey(initKey, result, 4, 10);
    for (int i = 0; i < 11; ++i) {
        for (int j = 0; j < 16; ++j) {
            printf("%02x ", result[i * 16 + j]);
        }
        printf("\n");
    }
    printf("\n");

    unsigned char col[16] = {
            0x12, 0x23, 0x34, 0x45,
            0x56, 0x67, 0x78, 0x89,
            0x9a, 0xab, 0xbc, 0xcd,
            0xde, 0xef, 0xf0, 0x01
    };
//    x2time(col[0]) ^ x3time(col[1]) ^ col[2] ^ col[3]
    printf("%x,%x,%x,%x,%x\n",x2time(col[0]), x3time(col[1]), col[2],col[3],x2time(col[0]) ^ x3time(col[1]) ^ col[2] ^ col[3]);
    MixColumns(col);
    for (int f = 0; f < 16; f++) {
        printf("%x,", col[f]);
    }
    printf("\n\n");


    unsigned char pt[16] = {
            0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x00, 0x11,
            0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99
    };
    unsigned char key[16] = {
            0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x00, 0x11,
            0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99
    };
    //定义原文pt
    //定义密钥key
    unsigned char expansionkey[11 * 16];
    int i;
    //加密过程
    ScheduleKey(key, expansionkey, 4, 10);//密钥扩展生成
    AesEncrypt(pt, expansionkey, 10);//调用AES 加密
    printf("ciphertext: ");

    //输出密文
    for (i = 0; i < 16; i++) {
        printf("%02x ", pt[i]);
    }

    return 0;
}
